package com.sali.b_design_pattern.f_responsibility_pattern.controller;


import com.alibaba.fastjson.JSON;
import com.sali.b_design_pattern.f_responsibility_pattern.strategy.method01.JobScheduler;
import com.sali.b_design_pattern.f_responsibility_pattern.strategy.method02.config.ProductCheckHandlerConfig;
import com.sali.b_design_pattern.f_responsibility_pattern.strategy.method02.handler.AbstractCheckHandler;
import com.sali.b_design_pattern.f_responsibility_pattern.strategy.method02.handler.HandlerClient;
import com.sali.b_design_pattern.f_responsibility_pattern.strategy.method02.pojo.entity.Result;
import com.sali.b_design_pattern.f_responsibility_pattern.strategy.method02.pojo.vo.ProductVO;
import org.junit.platform.commons.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Map;
import java.util.Objects;

@RestController
public class ResponseController {

    @Autowired
    JobScheduler jobScheduler;

    // 使用Spring注入:所有继承了AbstractCheckHandler抽象类的Spring Bean都会注入进来。Map的Key对应Bean的name,Value是name对应相应的Bean
    @Resource
    private Map<String, AbstractCheckHandler> handlerMap;


    @GetMapping("/response1")
    public Object response1() {
        jobScheduler.jobExec("sali-test");
        return Result.success();
    }

    @GetMapping("/response2")
    public Object response2() {

        // 测试输入
        ProductVO productVO = ProductVO.builder()
                .skuId(1L)
                .skuName("product A")
                .imgPath("/img_path")
                .price(new BigDecimal(1.1))
                .stock(1)
                .build();

        // 参数校验，使用责任链
        Result paramCheckResult = this.paramCheck(productVO);
        if (!paramCheckResult.isSuccess()) {
            return paramCheckResult;
        }

        return Result.success();
    }

    private Result paramCheck(ProductVO param) {

        //获取处理器配置：通常配置使用统一配置中心存储，支持动态变更
        ProductCheckHandlerConfig handlerConfig = this.getHandlerConfigFile();

        //获取处理器
        AbstractCheckHandler handler = this.getHandler(handlerConfig);

        //责任链：执行处理器链路
        Result executeChainResult = HandlerClient.executeChain(handler, param);
        if (!executeChainResult.isSuccess()) {
            System.out.println("创建商品 失败...");
            return executeChainResult;
        }

        //处理器链路全部成功
        return Result.success();
    }


    /**
     * 获取处理器配置：通常配置使用统一配置中心存储，支持动态变更
     *
     * @author sali
     */
    private ProductCheckHandlerConfig getHandlerConfigFile() {
        // 配置中心存储的配置
        String configJson = "{\"handler\":\"nullValueCheckHandler\",\"down\":true,\"next\":{\"handler\":\"priceCheckHandler\",\"next\":{\"handler\":\"stockCheckHandler\",\"next\":null}}}";
        // 转成Config对象
        ProductCheckHandlerConfig handlerConfig = JSON.parseObject(configJson, ProductCheckHandlerConfig.class);
        return handlerConfig;
    }


    /**
     * 获取处理器
     *
     * @author sali
     */
    private AbstractCheckHandler getHandler(ProductCheckHandlerConfig config) {
        //配置检查：没有配置处理器链路，则不执行校验逻辑
        if (Objects.isNull(config)) {
            return null;
        }

        //配置错误
        String handler = config.getHandler();
        if (StringUtils.isBlank(handler)) {
            return null;
        }

        //配置了不存在的处理器
        AbstractCheckHandler abstractCheckHandler = handlerMap.get(config.getHandler());
        if (Objects.isNull(abstractCheckHandler)) {
            return null;
        }

        //处理器设置配置Config
        abstractCheckHandler.setConfig(config);

        //递归设置链路处理器
        abstractCheckHandler.setNextHandler(this.getHandler(config.getNext()));

        return abstractCheckHandler;

    }

}
